﻿using EnetaMvc.Core.Domain.Common;
using EnetaMvc.Core.Repositories;
using EnetaMvc.Infrastructure;
using NHibernate;
using NHibernate.Criterion;
using System.Collections.Generic;

namespace EnetaMvc.Data.NHibernate.Repositories
{
    public class UserRepository : BaseRepository, IUserRepository
    {
        private readonly ISession _session;

        public UserRepository(IMapperSession session) : base(((NHSession)session).GetCurrentSession())
        {
            _session = ((NHSession)session).GetCurrentSession();
        }

        public User GetUserById(long id)
        {
            return _session.Get<User>(id);
        }

        public User GetUserByLiveIdToken(string liveIdToken)
        {
            var criteria = _session.CreateCriteria<User>()
                                   .Add(Expression.Eq("LiveIdToken", liveIdToken))
                                   .SetMaxResults(1);

            return criteria.UniqueResult<User>();
        }

        public User GetUserByUserName(string userName)
        {
            var criteria = _session.CreateCriteria<User>()
                                   .Add(Expression.Eq("UserName", userName))
                                   .SetMaxResults(1);

            return criteria.UniqueResult<User>();
        }

        public void SaveUser(User user)
        {
            if (user == null)
                return;

            SaveInTransaction(user);
        }

        public void DeleteUser(long id)
        {
            var user = GetUserById(id);
            if (user == null)
                return;

            _session.Delete(user);
        }

        public IList<MyRole> ListMyRoles()
        {
            return _session.CreateCriteria<MyRole>().List<MyRole>();
        }

        public MyRole GetMyRoleById(long id)
        {
            return _session.Get<MyRole>(id);
        }

        public IList<User> ListLatelyJoinedUsers(int count)
        {
            return _session.CreateCriteria<User>().AddOrder(Order.Desc("Id")).SetMaxResults(count).List<User>();
        }

        public IList<Role> ListRoles()
        {
            return _session.CreateCriteria<Role>().List<Role>();
        }


        public Role GetRoleByName(string roleName)
        {
            var criteria = _session.CreateCriteria<Role>()
                            .Add(Expression.Eq("Name", roleName))
                            .SetMaxResults(1);

            return criteria.UniqueResult<Role>();
        }

        public IList<User> FindUsers(string searchString)
        {
            var criteria = _session.CreateCriteria<User>()
                                   .Add(Expression.Like("UserName", "%" + searchString + "%"))
                                   .SetMaxResults(20);

            return criteria.List<User>();
        }
    }
}
